package java_thinking.unit_19;

/**
 * @Desc:   枚举实现单例模式
 *      1.使用SingletonEnum.INSTANCE进行访问，这样也就避免调用getInstance方法，更重要的是使用枚举单例的写法，我们完全不用考
 *        虑序列化和反射的问题。枚举序列化是由jvm保证的，每一个枚举类型和定义的枚举变量在JVM中都是唯一的，在枚举类型的序列化
 *        和反序列化上，Java做了特殊的规定：在序列化时Java仅仅是将枚举对象的name属性输出到结果中，反序列化的时候则是通过
 *        java.lang.Enum的valueOf方法来根据名字查找枚举对象。同时，编译器是不允许任何对这种序列化机制的定制的并禁用了
 *        writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法，从而保证了枚举实例的唯一性;
 * @author: cww
 * @DateTime: 2019-05-26 17:21
 */

public enum Singleton {
    INSTANCE;

    private SingletonClass instance;

    Singleton() {
        this.instance = new SingletonClass();
        System.out.println("枚举类构造函数");
    }

    public SingletonClass getInstance() {
        return this.instance;
    }

}

class SingletonClass {
    int i = 0;
    public SingletonClass() {
        System.out.println("SingletonClass被初始化 " + ++i + " 次");
    }
}

class SingletonTest {
    public static void main(String[] args) {
        SingletonClass instance1 = Singleton.INSTANCE.getInstance();
        SingletonClass instance2 = Singleton.INSTANCE.getInstance();
        System.out.println("instance1 == instance2: " + (instance1 == instance2));
    }
}
